package com.piz.model;

import static javax.persistence.GenerationType.IDENTITY;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.Valid;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

/**
 * UserDetails generated by hbm2java
 */
/**
 * @author prameetk.sharma
 *
 */
@Entity
@Table(name = "user")
public class User implements java.io.Serializable, UserDetails {

	/**
	 * 
	 */
	private static final long serialVersionUID = 560909136266931504L;
	private Long id;
	private String title;
	
	@NotEmpty
	@Size(min = 3, max = 12, message="First Name must be more than 3 and less than 12 characters")
	private String fname;
	
	
	@NotEmpty
	@Size(min = 3, max = 12, message="Last Name must be more than 3 and less than 12 characters")
	private String lname;
	
	@NotEmpty
	@Size(min = 6, max = 12, message="Password must be more than 6 and less than 12 characters")
	private String password;
	
	@NotEmpty
	private String cpassword;
	
	@NotEmpty
	@Size(min = 6, max = 12)
	private String username;
	
	@NotEmpty
	private String registerAs;
	
	@NotEmpty
	private String dob;
	
	private String anniversary;
	
	@Valid
	private UserContact contact;
	private Collection<GrantedAuthority> grantedAuthorities;
	private Set<Role> roles;
	

	/**
	 * 
	 */
	public User() {
	}

	

	/**
	 * @param title
	 * @param fname
	 * @param lname
	 * @param password
	 * @param cpassword
	 * @param username
	 * @param registerAs
	 * @param dob
	 * @param anniversary
	 * @param contact
	 * @param roles
	 */
	public User(String title, String fname, String lname, String password,
			String cpassword, String username, String registerAs, String dob,
			String anniversary, UserContact contact, Set<Role> roles) {
		this.title = title;
		this.fname = fname;
		this.lname = lname;
		this.password = password;
		this.cpassword = cpassword;
		this.username = username;
		this.registerAs = registerAs;
		this.dob = dob;
		this.anniversary = anniversary;
		this.contact = contact;
		this.roles = roles;
	}



	@Id
	@GeneratedValue(strategy = IDENTITY)
	@Column(name = "USER_ID", unique = true, nullable = false)
	public Long getId() {
		return this.id;
	}

	public void setId(Long id) {
		this.id = id;
	}


	@Column(name = "DOB")
	public String getDob() {
		return this.dob;
	}

	public void setDob(String dob) {
		this.dob = dob;
	}

	@Column(name = "ANNIVERSARY_DATE")
	public String getAnniversary() {
		return anniversary;
	}



	public void setAnniversary(String anniversary) {
		this.anniversary = anniversary;
	}
	
	@Column(name = "TITLE")
	public String getTitle() {
		return title;
	}
	
	
	public void setTitle(String title) {
		this.title = title;
	}

	@Column(name = "FNAME", nullable = false)
	public String getFname() {
		return this.fname;
	}

	public void setFname(String fname) {
		this.fname = fname;
	}
	

	@Column(name = "LNAME")
	public String getLname() {
		return this.lname;
	}

	public void setLname(String lname) {
		this.lname = lname;
	}

	@Column(name = "PASSWORD")
	public String getPassword() {
		return password;
	}



	public void setPassword(String password) {
		this.password = password;
	}


    @Transient
	public String getCpassword() {
		return cpassword;
	}



	public void setCpassword(String cpassword) {
		this.cpassword = cpassword;
	}



	@Column(name = "REGISTERAS")
	public String getRegisterAs() {
		return registerAs;
	}

	public void setRegisterAs(String registerAs) {
		this.registerAs = registerAs;
	}


	@OneToOne(cascade = CascadeType.ALL)
	public UserContact getContact() {
		return contact;
	}

	public void setContact(UserContact contact) {
		this.contact = contact;
	}

	@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
	@JoinTable(name = "USER_ROLE", joinColumns = { @JoinColumn(name = "USER_ID") }, inverseJoinColumns = { @JoinColumn(name = "ROLE_ID") })
	public Set<Role> getRoles() {
		return this.roles;
	}

	public void setRoles(Set<Role> userRoleses) {
		if(grantedAuthorities != null)
			grantedAuthorities.clear();
		else{
			grantedAuthorities = new ArrayList<GrantedAuthority>();
		}
		if(userRoleses != null){
			for(Role role : userRoleses){
				GrantedAuthorityImpl ga = new GrantedAuthorityImpl();
				ga.setAuthority(role.getName());
				grantedAuthorities.add(ga);
			}
		}
		this.roles = userRoleses;
	}



	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((roles == null) ? 0 : roles.hashCode());
		return result;
	}



	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (roles == null) {
			if (other.roles != null)
				return false;
		} else if (!roles.equals(other.roles))
			return false;
		return true;
	}



	@Override
	@Transient
	public Collection<GrantedAuthority> getAuthorities() {
		// TODO Auto-generated method stub
		return grantedAuthorities;
	}



	@Override
	@Column(name = "USERNAME")
	public String getUsername() {
		// TODO Auto-generated method stub
		return this.username;
	}

public void setUsername(String username) {
		this.username = username;
	}



	/*
	public void setUsername() {
		
		this.username =  username;
	}
*/
	@Override
	@Transient
	public boolean isAccountNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}



	@Override
	@Transient
	public boolean isAccountNonLocked() {
		// TODO Auto-generated method stub
		return true;
	}



	@Transient
	@Override
	public boolean isCredentialsNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}


	@Transient
	@Override
	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return true;
	}



}
